import React, {
 PureComponent, useContext, useEffect, useRef, useState,
} from 'react'
import {
 Dropdown, Form, Input, Menu, message, Modal, Popconfirm, Select, TreeSelect,
} from 'antd'
import list2tree from 'list2tree'
import { DownOutlined, ExclamationCircleFilled } from '@ant-design/icons'
import { history } from '@umijs/max'
import {
  BreadcrumbBar,
  InputSearch,
  ProTable,
  ProTableOperate,
  ProTableOptions,
  ProTree,
  searchTreeListByName,
} from '@/components'
import { IndexDetailModal, ResultModal } from './page-components'
import {
 alarmDisassociate, getDataAll, getTree, listCatalog, saveIndexCorrelation, saveTaskFlow,
} from './api'
import { regExp } from '@/utils/regExp.js'
import styles from './index.less'

const menus = [{ name: '指标管理' }]
const { OperateItem } = ProTableOperate
const { Option } = Select
const { Item } = Form
const { TextArea } = Input
const statusArr = ['待开发', '已完成']
const iconArr = ['icon-daikaifa', 'icon-chenggong']

const EditableContext = React.createContext(null)
const EditableRow = ({ index, ...props }) => {
  const [form] = Form.useForm()
  return (
    <Form form={form} component={false}>
      <EditableContext.Provider value={form}>
        <tr {...props} />
      </EditableContext.Provider>
    </Form>
  )
}

const EditableCell = ({
  title,
  editable,
  children,
  dataIndex,
  record,
  handleSave,
  ...restProps
}) => {
  const [editing, setEditing] = useState(false)
  const inputRef = useRef(null)
  const form = useContext(EditableContext)
  useEffect(() => {
    if (editing) {
      inputRef.current?.focus()
    }
  }, [editing])

  const toggleEdit = () => {
    setEditing(!editing)
    form.setFieldsValue({
      [dataIndex]: record[dataIndex],
    })
  }

  const save = async () => {
    try {
      const values = await form.validateFields()
      toggleEdit()
      if (record.version !== values.version) {
        handleSave({ ...record, ...values })
      }
    } catch (errInfo) {
      console.log('Save failed:', errInfo)
    }
  }

  let childNode = children

  if (editable) {
    if (record.versionList && record.versionList.length > 1) {
      childNode = editing ? (
        <Item
          style={{
            margin: 0,
          }}
          name={dataIndex}
          rules={[
            {
              required: true,
              message: '请选择版本号',
            },
          ]}
          initialValue={record.version}
        >
          <Select
            ref={inputRef}
            style={{ width: '100%' }}
            onChange={save}
            onBlur={save}
          >
            {record.versionList.map((item, index) => (
              <Option key={index} value={item}>
                {item}
              </Option>
            ))}
          </Select>
        </Item>
      ) : (
        <div
          className="editable-cell-value-wrap"
          style={{
            paddingRight: 24,
          }}
          onClick={toggleEdit}
        >
          {children}
        </div>
      )
    }
  }

  return <td {...restProps}>{childNode}</td>
}

const getNavTreeDataFunc = list2tree({
  idKey: 'id',
  parentIdKey: 'pid',
  newKey: {
    key: 'id',
    value: 'id',
    title: 'name',
  },
})

export default class IndexManagement extends PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      treeData: [],
      treeList: [],
      treeDataNew: [],
      loading: false,
      listLoading: false,
      indexSearchStatus: '',
      indexSearchName: '',
      selectedKeys: [],
      query: {},
      versionParams: [],
      indexId: '',
      isShowTaskFlow: false,
      columnsArr: [],
      rowsArr: [],
      resultTableName: '',
      columns: [
        {
          title: '指标名称',
          dataIndex: 'name',
          width: '13%',
          key: 'name',
        },
        {
          title: '业务定义',
          dataIndex: 'businessDef',
          width: '22%',
          key: 'businessDef',
        },
        {
          title: '指标结果',
          dataIndex: 'indexResult',
          width: '8%',
          key: 'indexResult',
          render: (text, record) => (
            record.indexCorrelation && record.indexCorrelation.tblName ? (
              <i
                className={`iconfont icon-zhexiantu-xianxing ${styles.index_result_icon}`}
                onClick={() => this.onResult(record)}
              />
            ) : '--'
          ),
        },
        {
          title: '版本',
          dataIndex: 'version',
          width: '9%',
          key: 'version',
          editable: true,
          render: (text, { version, versionList }) => (
            <div>
              {version} {versionList.length > 1 && <DownOutlined />}
            </div>
          ),
        },
        // {
        //   title: '数据owner',
        //   dataIndex: 'dataOwnerName',
        //   width: '10%',
        //   key: 'dataOwnerName',
        // },
        {
          title: '状态',
          dataIndex: 'status',
          width: '8%',
          key: 'status',
          render: (text, record) => (
            (record.status || record.status === 0) ? (
              <div className={styles.status_icon}>
                <i
                  className={`iconfont ${iconArr[record.status]}`}
                  style={{ marginRight: '4px' }}
                />
                {statusArr[record.status]}
                {/* {(record.status === 4 || record.status === 6) && (
                  <Popover
                    content={
                      <div>
                        指标计算任务异常，点击{' '}
                        <a>
                          查看详情
                        </a>
                      </div>
                    }
                  >
                    <i className="iconfont icon-yiwentishi" />
                  </Popover>
                )} */}
              </div>
            ) : (<span>--</span>)
          ),
        },
        {
          title: '更新时间',
          dataIndex: 'updateTime',
          width: '15%',
          key: 'updateTime',
        },
        {
          title: '操作',
          dataIndex: 'operation',
          width: '15%',
          key: 'operation',
          render: (text, record, index) => (
            <ProTableOptions>
              <span onClick={() => this.onCheck(record)} key="check">查看</span>
              {
                (
                  record.status === 0
                )
                  ? <span onClick={() => this.onRelation(record)} key="edit">指标关联</span> : null
              }
              {
                (
                  record.status === 1
                )
                  ? <span onClick={() => this.onChange(record)} key="change">变更关联</span> : null
              }
              {
                (
                  record.status === 1
                )
                  ? (
                    <Popconfirm
                      title="确定取消关联？"
                      okText="确定"
                      cancelText="取消"
                      onConfirm={() => this.onDisassociate(record)}
                      key="delPop"
                    >
                      <span>取消关联</span>
                    </Popconfirm>
                  ) : null
              }
              {
                (
                  record.status === 0
                )
                  ? (
                    <Dropdown overlay={(
                      <Menu>
                        <Menu.Item
                          key="1"
                          onClick={(event) => {
                            if (record.nodeId) {
                              // 跳转
                              history.push(`/data-development/offline/workflow-development?taskId=${record.nodeId}`)
                            } else {
                              this.setState({
                                isShowTaskFlow: true,
                                indexId: record.id,
                              }, () => {
                                this.procedureFormData.current?.resetFields()
                                this.procedureFormData.current?.setFieldsValue({
                                  name: record.name,
                                  remark: record.businessDef,
                                })
                              })
                            }
                            event.domEvent.stopPropagation()
                          }}
                        >
                          离线开发
                        </Menu.Item>
                        <Menu.Item
                          key="2"
                          onClick={(event) => {
                            event.domEvent.stopPropagation()
                          }}
                          disabled
                        >
                          实时开发
                        </Menu.Item>
                      </Menu>
                    )}
                    >
                      <span key="delete" onClick={e => e.preventDefault()}>
                        指标开发
                      </span>
                    </Dropdown>
                  ) : null
              }
            </ProTableOptions>
          ),
        },
      ],
    }

    this.modalRef = React.createRef()
    this.resultRef = React.createRef()
    this.procedureFormData = React.createRef()
  }

  componentDidMount() {
    this.updateList()
    this.getDirTree()
  }

  // 获取工作流目录
  getDirTree = (id, cb) => {
    this.setState({ loading: true })
    getTree({ id: id || 2 }).then((res) => {
      this.setState({
        dirTree: res,
        loading: false,
      }, () => {
        cb && cb()
      })
    }, (error) => {
      this.setState({ loading: false })
    })
  }

  // 点击查看按钮
  onCheck = (record) => {
    this.modalRef.current?.onCheckOpen(record)
  }

  // 点击指标关联
  onRelation = (record) => {
    this.modalRef.current?.onEditOpen(record)
  }

  onChange = (record) => {
    this.modalRef.current?.onChangeOpen(record)
  }

  // 取消关联
  onDisassociate = (record) => {
    const postFun = () => {
      saveIndexCorrelation({
        id: record.id,
        indexCorrelation: {},
      }).then(
        (resObj) => {
          message.success('取消关联成功')
          this.setState({
            loading: false,
          }, () => {
            this.fetchData()
          })
        },
        (error) => {
          console.log(error)
          this.setState({ loading: false })
        },
      )
    }
    this.setState({ loading: true })
    alarmDisassociate({
      indexId: record.id,
    }).then(
      (res) => {
        if (res) {
          Modal.confirm({
            title: res,
            icon: <ExclamationCircleFilled />,
            content: '是否继续取消关联，请谨慎操作',
            okText: '取消关联',
            cancelText: '否',
            okButtonProps: {
              danger: true,
            },
            onOk: () => {
              postFun()
            },
          })
        } else {
          postFun()
        }
      },
      (error) => {
        console.log(error)
        this.setState({ loading: false })
      },
    )
  }

  // 点击指标结果
  onResult = (record) => {
    this.setState({ loading: true })
    getDataAll({
      targetTblName: record.indexCorrelation.tblName,
    }).then(
      (res) => {
        this.setState({
          loading: false,
          columnsArr: res.columns ? res.columns : [],
          rowsArr: res.rows ? res.rows : [],
          resultTableName: record.indexCorrelation.tblName,
        }, () => {
          this.resultRef.current?.openModal()
        })
      },
      (error) => {
        this.setState({ loading: false })
      },
    )
  }

  // 渲染列表节点
  renderTreeNodes = (data) => {
    const tempArr = []
    data.map((item) => {
      const {
        name, id, nodeType,
      } = item
      const defaultIconFun = props => {
        const { selectedKeys } = this.state
        if (selectedKeys && selectedKeys[0] === props.data.key) {
          return props.expanded ? <i className="iconfont-colour2 icon-wenjianjia-dakaihover" /> : <i className="iconfont-colour2 icon-wenjianjia-morenhover" />
        }
        return props.expanded ? <i className="iconfont-colour2 icon-wenjianjia-dakai" /> : <i className="iconfont-colour2 icon-wenjianjia-moren" />
      }
      const tempObj = {
        icon: defaultIconFun,
        key: id,
        nodeType,
      }
      if (item.children) {
        tempObj.children = this.renderTreeNodes(item.children)
      }
      tempObj.title = name
      tempArr.push(tempObj)
    })
    return tempArr
  }

  fetchData = async () => {
    const {
      indexSearchStatus, indexSearchName, selectedKeys, versionParams,
    } = this.state
    const tempQuery = {}
    if (indexSearchStatus && indexSearchStatus !== '') tempQuery.status = indexSearchStatus
    if (indexSearchName && indexSearchName !== '') tempQuery.name = indexSearchName
    if (selectedKeys && selectedKeys.length > 0) tempQuery.catalogId = selectedKeys[0]
    if (versionParams && versionParams.length) tempQuery.versionParams = versionParams
    this.setState({
      query: tempQuery,
    })
  }

  // 列表选择回调
  onSelect = (selectedKeys) => {
    this.setState({
      selectedKeys,
    }, () => {
      this.fetchData()
    })
  }

  handleSave = (obj) => {
    const { versionParams } = this.state
    const tempArr = versionParams.concat([])
    const item = tempArr.find((param) => param.indexNum === obj.indexNum)
    if (item) {
      item.version = obj.version
    } else {
      tempArr.push({
        indexNum: obj.indexNum,
        version: obj.version,
      })
    }
    this.setState({
      versionParams: tempArr,
    }, () => {
      this.fetchData()
    })
  };

  // 关联成功后的回调
  onCloseCallBack = () => {
    this.fetchData()
  }

  // 离线开发确认
  onTaskFlowOk = () => {
    this.procedureFormData.current.validateFields().then(values => {
      this.setState({ confirmLoading: true })
      const postObj = {
        name: values.name,
        pid: values.pid ? values.pid : 2,
        remark: values.remark,
        indexId: this.state.indexId,
      }
      saveTaskFlow(postObj).then((res) => {
        if (res.status === 200) {
          this.setState({
            isShowTaskFlow: false,
          }, () => {
            this.fetchData()
          })
          message.success('新建成功')
          this.setState({ confirmLoading: false })
        } else {
          message.warning(res.msg)
          this.setState({ confirmLoading: false })
        }
      })
    })
  }

  // 刷新左侧列表
  updateList() {
    this.setState({ listLoading: true })
    listCatalog().then(
      (res) => {
        this.setState({
          treeData: getNavTreeDataFunc(res),
          treeList: res,
          treeDataNew: getNavTreeDataFunc(res),
          listLoading: false,
        })
      },
      (error) => {
        console.log(error)
        this.setState({ listLoading: false })
      },
    )
  }

  render() {
    const {
      treeData, treeList, treeDataNew, selectedKeys, indexSearchStatus, indexSearchName,
      loading, listLoading,
    } = this.state
    const descRe = regExp.proName(0, 128)

    const components = {
      body: {
        row: EditableRow,
        cell: EditableCell,
      },
    }
    const columns = this.state.columns.map((col) => {
      if (!col.editable) {
        return col
      }

      return {
        ...col,
        onCell: (record) => ({
          record,
          editable: col.editable,
          dataIndex: col.dataIndex,
          title: col.title,
          handleSave: this.handleSave,
        }),
      }
    })
    return (
      <div className={`${styles.page_content_with_breadcrumb} ${styles.page_content_tabs_height} ${styles.index_management}`}>
        <BreadcrumbBar menu={menus} />
        <div className={styles.page_content}>
          <div className={styles.page_content_left}>
            <ProTree
              showTitle={false}
              showSearch
              treeData={treeDataNew}
              renderTreeNodes={this.renderTreeNodes}
              selectedKeys={selectedKeys}
              onSelect={this.onSelect}
              loading={listLoading}
              ref={(dev) => (this.tree = dev)}
              search={(name) => {
                const searchTree = searchTreeListByName(
                  name,
                  treeList,
                  'name',
                )
                const treeDataNews = getNavTreeDataFunc(
                  searchTree.result,
                )
                this.setState(
                  {
                    treeDataNew: treeDataNews,
                  },
                  () => {
                    this.tree.onExpand(searchTree.fatchIds)
                  },
                )
              }}
            />
          </div>
          <div className={styles.page_content_right}>
            <ProTableOperate
              toggleOperate={false}
              unfolded // 默认展开状态
            >
              <OperateItem align="left">
                <span>状态</span>
                <Select
                  value={indexSearchStatus}
                  onChange={(e) => {
                    this.setState({
                      indexSearchStatus: `${e}`,
                    }, () => {
                      this.fetchData()
                    })
                  }}
                >
                  <Option value="" key="全部">
                    全部
                  </Option>
                  {
                    statusArr.map((item, index) => (
                      <Option value={`${index}`} key={`${index}`}>
                        {item}
                      </Option>
                    ))
                  }
                </Select>
              </OperateItem>
              <OperateItem align="left">
                <InputSearch
                  placeholder="请输入指标名称进行搜索"
                  value={indexSearchName}
                  onChange={(e) => {
                    this.setState({
                      indexSearchName: e.target.value,
                    }, () => {
                      this.fetchData()
                    })
                  }}
                  onSearch={this.fetchData}
                />
              </OperateItem>
            </ProTableOperate>
            <ProTable
              rowKey="id"
              columns={columns}
              loading={loading}
              query={this.state.query}
              method="post"
              url="/api/v1/index/indexList"
              components={components}
            />
          </div>
        </div>
        <Modal
          width={600}
          title="新建工作流程"
          visible={this.state.isShowTaskFlow}
          confirmLoading={this.state.confirmLoading}
          cancelText="取消"
          okText="保存"
          onOk={this.onTaskFlowOk}
          onCancel={() => {
            this.setState({
              isShowTaskFlow: false,
            })
          }}
          maskClosable={false}
        >
          <div className={styles.file_box}>
            <Form
              labelCol={{
                sm: { span: 5 },
              }}
              wrapperCol={{
                sm: { span: 15 },
              }}
              ref={this.procedureFormData}
            >
              <Item
                label="工作流程名称"
                name="name"
                labelAlign="right"
                rules={[
                  { required: true, message: '请输入工作流程名称' },
                  {
                    required: false,
                    pattern: new RegExp(regExp.name(2, 64).reg, 'g'),
                    message: regExp.name(2, 64).text,
                  },
                ]}
              >
                <Input placeholder="请输入工作流程名称" />
              </Item>
              <Item
                label="父级目录"
                labelAlign="right"
                name="pid"
              >
                <TreeSelect
                  treeData={this.state.dirTree || []}
                  dropdownStyle={{ maxHeight: '4rem', overflow: 'auto' }}
                  placeholder="选择父级目录"
                  allowClear
                  fieldNames={
                    {
                      label: 'name',
                      value: 'id',
                      children: 'childs',
                    }
                  }
                  filterTreeNode={(input, treeNode) => treeNode.name.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  showSearch
                  treeDefaultExpandAll
                />
              </Item>
              <Item
                label="描述"
                labelAlign="right"
                name="remark"
                rules={[
                  { required: false },
                  {
                    pattern: new RegExp(descRe.reg, 'g'),
                    message: descRe.text,
                  },
                ]}
              >
                <TextArea
                  placeholder="请输入工作流程业务描述"
                  autoSize={{ minRows: 3, maxRows: 6 }}
                />
              </Item>
            </Form>
          </div>
        </Modal>
        <IndexDetailModal
          ref={this.modalRef}
          closeCallBack={this.onCloseCallBack}
        />
        <ResultModal
          ref={this.resultRef}
          columns={this.state.columnsArr}
          rows={this.state.rowsArr}
          targetTblName={this.state.resultTableName}
        />
      </div>
    )
  }
}
